package org.zjvis.datascience.common.widget;

import com.google.common.collect.Maps;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import org.docx4j.XmlUtils;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zjvis.datascience.common.widget.constant.WordTemplateConstant;
import org.zjvis.datascience.common.widget.vo.NetImage;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @description TODO
 * @date 2022/1/26
 */
public final class WordGeneratorUtil {
    private final static Logger logger = LoggerFactory.getLogger("WordGeneratorUtil");

    private static Configuration configuration = null;
    private static Map<String, Template> allTemplates = null;
    private static final String TEMPLATE_URL = "/template/word";

    /**
     * 模板常量类配置
     */
    public static final class FreemarkerTemplate {
        public static final String Test = "test1";

    }

    static {
        configuration = new Configuration(Configuration.VERSION_2_3_28);
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassForTemplateLoading(WordGeneratorUtil.class, TEMPLATE_URL);
        allTemplates = new HashMap(4);
        try {
            // 载入需要的模板文件
            allTemplates.put(FreemarkerTemplate.Test, configuration.getTemplate(FreemarkerTemplate.Test + ".ftl"));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 创建doc 文档
     * dataMap 数据，需要对应模板的占位符，否则会出错
     *
     * @param dataMap                数据
     * @param wordName               word 报表的名称
     * @param freemarkerTemplateName 指定需要使用哪个freemarker模板
     * @return
     */
    public static File createDoc(String freemarkerTemplateName, String wordName, Map<String, String> dataMap) {
        try {
            File f = new File(wordName);
            Template t = allTemplates.get(freemarkerTemplateName);
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w = new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8);
            t.process(dataMap, w);
            w.close();
            return f;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException("生成word文档失败");
        }
    }

    public static String wrapText(String htmlContent) {
        try {
            htmlContent =  htmlContent.replace("&nbsp;", "\u00A0");
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
            XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(wordMLPackage);
            wordMLPackage.getMainDocumentPart().getContent().addAll(
                    XHTMLImporter.convert(htmlContent, null));

            String s = XmlUtils.marshaltoString(wordMLPackage.getMainDocumentPart().getJaxbElement(), true, false);
            Matcher m = Pattern.compile("<w:p>(.+?)</w:p>").matcher(s);
            return m.find() ? m.group(1) : StringUtils.EMPTY;
        } catch (Docx4JException e) {
            logger.error("wrap text failed, since {}", e.getMessage());
        }
        return StringUtils.EMPTY;
    }

    public static NetImage downloadImage(String netImagePath, String imgSuffix) {
        NetImage netImage = new NetImage(netImagePath);
        try {
            URL url = new URL(netImagePath);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);

            InputStream is = conn.getInputStream();
            netImage.read(ImageIO.read(is), imgSuffix);
            is.close();
        } catch (IOException e) {
            logger.error("download image failed, since {}", e.getMessage());
            netImage = new NetImage();
        }
        return netImage;
    }


}